﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using System.IO.IsolatedStorage;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Controls.Primitives;
using Microsoft.Phone.Net.NetworkInformation;
using System.Windows.Threading;
using System.Device.Location;

namespace NearChat
{
    public partial class Cerca : PhoneApplicationPage
    {
        //storage dell'applicazione
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

        //classe per la geo-localizzazione
        private static GeoCoordinateWatcher watcher;

        //uri della pagina
        Uri myDBuri;

        private string user;
        private string IDuser;
        private double lat;
        private double lon;

        private string function="";
        private string postUpdate = "";

        Style CanvasStyle = Application.Current.Resources["ListaPreferiti"] as Style;
        Style CanvasBorderStyle = Application.Current.Resources["BorderCanvas"] as Style;
        Style ImageBorderStyle = Application.Current.Resources["ImgProfilo"] as Style;
        Style TextBlockStyle = Application.Current.Resources["Name"] as Style;
        Style PreferitiStyle = Application.Current.Resources["Preferiti"] as Style;
        Style BlackListStyle = Application.Current.Resources["BlackList"] as Style;
        Style ProfileStyle = Application.Current.Resources["Profile"] as Style;
        Style NewMessageTextStyle = Application.Current.Resources["NewMessageText"] as Style;
        Style NewMessageBorderStyle = Application.Current.Resources["NewMessageBorder"] as Style;

        public Cerca()
        {
            InitializeComponent();

            //attivo il lettore GPS
            watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            string functOUT = string.Empty;
            if (NavigationContext.QueryString.TryGetValue("funct", out functOUT))
                function = functOUT;
        }//OnNavigatedTo

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            //se c'è qualcosa lo cancello
            listCerca.Items.Clear();

            //da dove vengo?
            switch (function)
            {
                case "cerca":
                    {
                        myDBuri = new Uri("http://www.nearchat.altervista.org/FindNearFriends.php");
                        break;
                    }
                case "preferiti":
                    {
                        myDBuri = new Uri("http://www.nearchat.altervista.org/listaPreferiti.php");
                        break;
                    }
                case "bloccati":
                    {
                        myDBuri = new Uri("http://www.nearchat.altervista.org/listaNera.php");
                        break;
                    }
                default:
                    {
                        myDBuri = new Uri("http://www.nearchat.altervista.org/FindNearFriends.php");
                        break;
                    }
            }

            //salvo i dati
            user = appSettings["user"].ToString();
            IDuser = appSettings["ID"].ToString();

            watcher.Start();
            GeoCoordinate co = watcher.Position.Location;

            lat = co.Latitude;
            lon = co.Longitude;

            //controllo dati
            if (!(double.IsNaN(lat) || double.IsNaN(lon)))//sono leggibili
            {
                //salvo i dati in locale, già pronti per il DB
                if (appSettings.Contains("lat"))
                {
                    appSettings["lat"] = lat.ToString().Replace(',', '.');
                    appSettings["lon"] = lon.ToString().Replace(',', '.');
                }
                else
                {
                    appSettings.Add("lat", lat.ToString().Replace(',', '.'));
                    appSettings.Add("lon", lon.ToString().Replace(',', '.'));
                }

                //se mi sono geolocalizzato
                if (NetworkInterface.GetIsNetworkAvailable())//se c'è rete per fare la query
                {
                    //faccio request PHP al DB
                    HttpWebRequest cercaRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                    cercaRequest.Method = "POST";
                    cercaRequest.ContentType = "application/x-www-form-urlencoded";
                    cercaRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), cercaRequest);
                }
                else
                    MessageBox.Show("connection error, please retry later.");
            }
            else //se uno dei due è inleggibile
                MessageBox.Show("impossible get your GPS position, please retry later.");
        }//PhoneApplicationPage_Loaded

        void GetRequestStreamCallback(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            string postData = "apikey=4nn!eSupp0rt&ID=" + IDuser + "&lat=" + lat.ToString().Replace(',', '.') + "&lon=" + lon.ToString().Replace(',', '.');
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
        }//GetRequestStreamCallback

        void GetResponsetStreamCallback(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingCerca(result));
            }
        }//GetResponsetStreamCallback

        void ParsingCerca(string result)
        {
            //controllo result
            if (result != "")//ho trovato utenti
            {
                //parsing e creo lista
                string[] ris = majorSplit(result);
                foreach (string record in ris)
                {
                    string[] dati = minorSplit(record);
                    string index = dati[0];
                    string nome = dati[1];
                    string imageURL = dati[2];
                    string lat=dati[3];
                    string lon = dati[4];
                    string stateStella = dati[5];
                    string stateDivieto = dati[6];

                    string newMess="";
                    if(function=="cerca")
                        newMess = dati[7]; 

                    //inserisco nel canvas
                    Canvas CanvasPreferito = new Canvas();
                    CanvasPreferito.Tag = index;
                    CanvasPreferito.Style = CanvasStyle;

                    Border CanvasBorder = new Border();
                    CanvasBorder.Style = CanvasBorderStyle;
                    CanvasBorder.Tag = index;
                    //se l'utente è in divieto non abilito la chat
                    if (stateDivieto == "")//l'utente non è in divieto
                        CanvasBorder.Tap += new EventHandler<GestureEventArgs>(CanvasPreferito_Tap);//abilito il tap per la chat

                    Border CanvasImage = new Border();
                    CanvasImage.Style = ImageBorderStyle;
                    CanvasImage.Tag = imageURL;
                    CanvasImage.Loaded += new RoutedEventHandler(CanvasImage_Loaded);

                    TextBlock CanvasUsername = new TextBlock();
                    CanvasUsername.Text = nome;
                    CanvasUsername.Style = TextBlockStyle;

                    ToggleButton CanvasStella = new ToggleButton();
                    CanvasStella.Style = PreferitiStyle;
                    CanvasStella.IsChecked = (stateStella != "");
                    CanvasStella.Tap += new EventHandler<GestureEventArgs>(CanvasStella_Tap);
                    CanvasStella.Checked += new RoutedEventHandler(CanvasStella_Checked);
                    CanvasStella.Unchecked += new RoutedEventHandler(CanvasStella_Unchecked);
                    CanvasStella.Loaded += new RoutedEventHandler(CanvasStella_Loaded);
                    CanvasStella.Tag = index;

                    ToggleButton CanvasDivieto = new ToggleButton();
                    CanvasDivieto.Style = BlackListStyle;
                    CanvasDivieto.IsChecked = (stateDivieto != "");
                    CanvasDivieto.Tap += new EventHandler<GestureEventArgs>(CanvasDivieto_Tap);
                    CanvasDivieto.Checked += new RoutedEventHandler(CanvasDivieto_Checked);
                    CanvasDivieto.Unchecked += new RoutedEventHandler(CanvasDivieto_Unchecked);
                    CanvasDivieto.Loaded += new RoutedEventHandler(CanvasDivieto_Loaded);
                    CanvasDivieto.Tag = index;

                    Button CanvasProfilo = new Button();
                    CanvasProfilo.Style = ProfileStyle;
                    CanvasProfilo.Click += new RoutedEventHandler(CanvasProfilo_Click);
                    CanvasProfilo.Loaded += new RoutedEventHandler(CanvasProfilo_Loaded);
                    CanvasProfilo.Tag = index;

                    TextBlock CanvasNumeroMessaggiText = new TextBlock();
                    CanvasNumeroMessaggiText.Style = NewMessageTextStyle;
                    CanvasNumeroMessaggiText.Text = newMess;

                    Border CanvasNumeroMessaggiBorder = new Border();
                    CanvasNumeroMessaggiBorder.Style = NewMessageBorderStyle;
                    CanvasNumeroMessaggiBorder.Child = CanvasNumeroMessaggiText;


                    if (newMess == "" || newMess=="0")//non ho messaggi
                    {
                        CanvasNumeroMessaggiBorder.Visibility = System.Windows.Visibility.Collapsed;//lo nascondo
                    }
                    else //c'è almeno un messaggio
                    {
                        CanvasNumeroMessaggiBorder.Visibility = System.Windows.Visibility.Visible;//lo mostro
                    }

                    CanvasPreferito.Children.Add(CanvasImage);
                    CanvasPreferito.Children.Add(CanvasUsername);
                    CanvasPreferito.Children.Add(CanvasBorder);
                    CanvasPreferito.Children.Add(CanvasStella);
                    CanvasPreferito.Children.Add(CanvasDivieto);
                    CanvasPreferito.Children.Add(CanvasProfilo);
                    CanvasPreferito.Children.Add(CanvasNumeroMessaggiBorder);

                    //aggiungo alla lista
                    listCerca.Items.Add(CanvasPreferito);
                }
            }
        }//ParsingCerca

        //splitta la stringa passata in base a |
        private string[] minorSplit(string result)
        {
            return result.Split('|');
        }

        //splitta la stringa passata in base a §
        private string[] majorSplit(string result)
        {
            return result.Split('§');
        }

        private void CanvasImage_Loaded(object sender, RoutedEventArgs e)
        {
            Border b = sender as Border;
            string url = b.Tag.ToString();
            BitmapImage urlProfilo = new BitmapImage(new Uri(url, UriKind.Absolute));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = urlProfilo;
            sfondo.ImageSource = src;
            b.Background = sfondo;
        }

        private void CanvasProfilo_Loaded(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            BitmapImage Profilo = new BitmapImage(new Uri("img/List.png", UriKind.Relative));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Profilo;
            sfondo.ImageSource = src;
            b.Background = sfondo;
        }

        private void CanvasProfilo_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            string TagOUT = (string)b.Tag;

            NavigationService.Navigate(new Uri("/Profilo.xaml?ID=" + TagOUT, UriKind.Relative));//cambio della pagina
        }

        private void CanvasStella_Loaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            BitmapImage Stella;

            if ((bool)tb.IsChecked)
                Stella = new BitmapImage(new Uri("img/starUp.png", UriKind.Relative));
            else
                Stella = new BitmapImage(new Uri("img/starDown.png", UriKind.Relative));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Stella;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage StellaON = new BitmapImage(new Uri("img/starUp.png", UriKind.Relative));

            ImageSource src = StellaON;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Unchecked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage StellaOFF = new BitmapImage(new Uri("img/starDown.png", UriKind.Relative));

            ImageSource src = StellaOFF;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Tap(object sender, GestureEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            string TagOUT = tb.Tag.ToString();

            if ((bool)tb.IsChecked)//l'ho appena attivato, devo renderlo preferito
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=1&blacklist=0";
            }
            else //l'ho appena disattivato, lo tolgo dai preferiti
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=0";
            }

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                //faccio request PHP al DB
                Uri myDBuri = new Uri("http://www.nearchat.altervista.org/updateState.php");
                HttpWebRequest stateRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                stateRequest.Method = "POST";
                stateRequest.ContentType = "application/x-www-form-urlencoded";
                stateRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackState), stateRequest);
            }
            else
            {
                MessageBox.Show("connection error, please retry later.");
                //refresh
                listCerca_Loaded();
            }
        }

        private void CanvasDivieto_Loaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            BitmapImage Divieto;

            if ((bool)tb.IsChecked)
                Divieto = new BitmapImage(new Uri("img/BlackListUp.png", UriKind.Relative));
            else
                Divieto = new BitmapImage(new Uri("img/BlackListDown.png", UriKind.Relative));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Divieto;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage DivietoON = new BitmapImage(new Uri("img/BlackListUp.png", UriKind.Relative));

            ImageSource src = DivietoON;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Unchecked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage DivietoOFF = new BitmapImage(new Uri("img/BlackListDown.png", UriKind.Relative));

            ImageSource src = DivietoOFF;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Tap(object sender, GestureEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            string TagOUT = tb.Tag.ToString();

            if ((bool)tb.IsChecked)//l'ho appena attivato, devo bloccarlo
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=1";
            }
            else //l'ho appena disattivato, lo sblocco dalla blacklist
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=0";
            }

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                //faccio request PHP al DB
                Uri myDBuri = new Uri("http://www.nearchat.altervista.org/updateState.php");
                HttpWebRequest stateRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                stateRequest.Method = "POST";
                stateRequest.ContentType = "application/x-www-form-urlencoded";
                stateRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackState), stateRequest);
            }
            else
            {
                MessageBox.Show("connection error, please retry later.");
                //refresh
                listCerca_Loaded();
            }
        }

        private void CanvasPreferito_Tap(object sender, GestureEventArgs e)
        {
            Border c = sender as Border;
            string indicecliccato = c.Tag.ToString();

            NavigationService.Navigate(new Uri("/Chat.xaml?ID=" + indicecliccato, UriKind.Relative));//cambio della pagina
        }

        void GetRequestStreamCallbackState(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            byte[] byteArray = Encoding.UTF8.GetBytes(postUpdate);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackState), myRequest);
        }//GetRequestStreamCallbackState

        void GetResponsetStreamCallbackState(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingUpdateState(result));
            }
        }//GetResponsetStreamCallbackState

        void ParsingUpdateState(string result)
        {
            if (result != "")//successo errore
            {
                string[] ris = majorSplit(result);
                ris = minorSplit(ris[0]);//sono sicuro che è uno solo

                if (ris[0] == "ERRORE")
                    MessageBox.Show(ris[1]);//stampo l'errore
            }
            else //non sono avvenuti errori
            {
                //refresh
                listCerca_Loaded();
            }
        }//ParsingUpdateState

        private void Image_Tap(object sender, GestureEventArgs e)
        {
            GeoCoordinate co = watcher.Position.Location;

            lat = co.Latitude;
            lon = co.Longitude;

            //controllo dati
            if (!(double.IsNaN(lat) || double.IsNaN(lon)))//sono leggibili
            {
                //salvo i dati in locale, già pronti per il DB
                if (appSettings.Contains("lat"))
                {
                    appSettings["lat"] = lat.ToString().Replace(',', '.');
                    appSettings["lon"] = lon.ToString().Replace(',', '.');
                }
                else
                {
                    appSettings.Add("lat", lat.ToString().Replace(',', '.'));
                    appSettings.Add("lon", lon.ToString().Replace(',', '.'));
                }

                //se mi sono geolocalizzato
                if (NetworkInterface.GetIsNetworkAvailable())//se c'è rete per fare la query
                {
                    //faccio request PHP al DB
                    Uri myDBuri = new Uri("http://www.nearchat.altervista.org/updateGPS.php");
                    HttpWebRequest gpsRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                    gpsRequest.Method = "POST";
                    gpsRequest.ContentType = "application/x-www-form-urlencoded";
                    gpsRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackGPS), gpsRequest);
                }
                else
                    MessageBox.Show("connection error, please retry later.");
            }
            else //se uno dei due è inleggibile
                MessageBox.Show("impossible get your GPS position, please retry later.");
        }

        void GetRequestStreamCallbackGPS(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            string postData = "apikey=4nn!eSupp0rt&user=" + IDuser + "&lat=" + lat.ToString().Replace(',', '.') + "&lon=" + lon.ToString().Replace(',', '.');
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackGPS), myRequest);
        }//GetRequestStreamCallback

        void GetResponsetStreamCallbackGPS(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingUpdateGPS(result));
            }
        }//GetResponsetStreamCallback

        void ParsingUpdateGPS(string result)
        {
            if (result != "")//successo errore
            {
                string[] ris = majorSplit(result);
                ris = minorSplit(ris[0]);//sono sicuro che è uno solo

                if (ris[0] == "ERRORE")
                    MessageBox.Show(ris[1]);//stampo l'errore
            }
            else
            {
                //refresh
                listCerca_Loaded();     
            }

        }//ParsingUpdateGPS

        private void listCerca_Loaded()
        {
            //se c'è qualcosa lo cancello
            listCerca.Items.Clear();

            //il myDBuri contiene già la pagina da refreshare
 
            watcher.Start();
            GeoCoordinate co = watcher.Position.Location;

            lat = co.Latitude;
            lon = co.Longitude;

            //controllo dati
            if (!(double.IsNaN(lat) || double.IsNaN(lon)))//sono leggibili
            {
                //salvo i dati in locale, già pronti per il DB
                if (appSettings.Contains("lat"))
                {
                    appSettings["lat"] = lat.ToString().Replace(',', '.');
                    appSettings["lon"] = lon.ToString().Replace(',', '.');
                }
                else
                {
                    appSettings.Add("lat", lat.ToString().Replace(',', '.'));
                    appSettings.Add("lon", lon.ToString().Replace(',', '.'));
                }

                //se mi sono geolocalizzato
                if (NetworkInterface.GetIsNetworkAvailable())//se c'è rete per fare la query
                {
                    //faccio request PHP al DB
                    HttpWebRequest cercaRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                    cercaRequest.Method = "POST";
                    cercaRequest.ContentType = "application/x-www-form-urlencoded";
                    cercaRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), cercaRequest);
                }
                else
                    MessageBox.Show("connection error, please retry later.");
            }
            else //se uno dei due è inleggibile
                MessageBox.Show("impossible get your GPS position, please retry later.");
        }

    }
}